use std::path::PathBuf;

use futures::{select, FutureExt};
use log::info;
use tokio::io::{self, AsyncBufReadExt, BufReader};

pub use sim_common::*;

mod configure;
pub use configure::*;

mod node_id;
pub use node_id::*;

mod carla_proc;
pub use carla_proc::*;

mod server;

#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<()> {
    env_logger::init();

    info!("Start sim server...");

    // 从文件读取配置
    let root = PathBuf::from(std::env::var("SIM_SERVER_ROOT").map_or("".to_string(), |v| v));
    let config_path = root.join("etc").join("sim_server.toml");
    let config = Configure::load(&root, &config_path)?;
    info!("Broker uri: {}", config.broker_uri);
    info!("Carla path: {}", config.carla_path.display());
    info!("Carla addr: {}", config.carla_addr);

    // 启动carla进程
    let _carla = CarlaProcess::new(&config).await?;

    // 从文件读取node_id
    // TODO: 目前没有对重复节点id进行处理
    let node_id_path = root
        .join("var")
        .join("lib")
        .join("sim_server")
        .join("node_id");
    let node_id = NodeId::load(&node_id_path).await?;
    info!("Node id: {}", node_id);

    // 输入回车退出
    info!("Enter for stop");
    let mut buf = String::new();
    let mut reader = BufReader::new(io::stdin());

    select! {
        _ = server::start(config, node_id).fuse() => {
            info!("Stop");
        }

        _ = reader.read_line(&mut buf).fuse() => {
            info!("Entered");
        }
    }

    Ok(())
}
